<?php
namespace App\WebSocket;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\EasySwoole\Swoole\Task\TaskManager; //异步任务模板
use EasySwoole\Socket\AbstractInterface\Controller;
use App\Pool\MysqlObject; 
use App\Pool\MysqlPool;//载入mysqlpool
use App\Pool\RedisPool;//载入redispool
use App\Pool\RedisObject;
use App\WebSocket\RsaEncryp; //载入加密解密类
use App\Model\MessageOfflineModel;
use App\Model\ConditionBeanModel;
use App\Model\HistoryMsgModel;
use EasySwoole\Spl\SplBean;
use App\WebSocket\MsgOffLine; //载入离线消息类
use App\WebSocket\HistoryMsg; //载入历史消息类
use App\WebSocket\GroupSend; //载入群组类
use App\Process\SendFailTask;
use App\WebSocket\PushContent;
/**
 * Class Index
 *
 * 此类是默认的 websocket 消息解析后访问的 控制器
 *
 * @package App\WebSocket
 */
class Index extends Controller
{
    public function __construct(){
		parent::__construct();
      	//$this->dbmodel = MysqlPool::defer();
      	
    }
  	//发送消息函数
    public function hello()
    {
      //获取加密解密数据
      $resultData = RsaEncryp::dataDecrypt($this->caller()->getArgs()['data'],$this->caller()->getArgs()['aesEncryptKey'],$this->caller()->getArgs()['sign']);
     var_dump($resultData);
      //个人消息
      $redis = RedisPool::defer();
      $newData = [
			'fromUserId'=>$resultData["decryptData"]["sendUserId"],
			'toUserId'=>$resultData["decryptData"]["targetId"],
			'objectName'=>'',
			'content'=>$resultData["encryptContent"],
			'channelType'=>$resultData["decryptData"]["conversationType"],
      		'messageType'=>$resultData["decryptData"]["messageType"],
			'msgTimestamp'=>$resultData["decryptData"]["sendTimeStamp"],
			'source'=>'',
			'groupUserIds'=>"[]",
			'aeskey'=>$resultData["aesEncryptKey"],
			'userset'=>$resultData["decryptData"]['sendUserId'].','.$resultData["decryptData"]['targetId'],
			'readStatus'=>$resultData["decryptData"]["readStatus"],
			'messageId' =>$resultData["decryptData"]["messageId"]
		];
      //推送消息重构
      $pushContent = json_decode($resultData["decryptData"]["messageContent"],true);
        $pushData = [
			'sendUserId'=>$resultData["decryptData"]["sendUserId"],
			'targetId'=>$resultData["decryptData"]["targetId"],
			'content'=>$pushContent["content"],
			'conversationType'=>$resultData["decryptData"]["conversationType"],
      		'messageType'=>$resultData["decryptData"]["messageType"],
			'aeskey'=>$resultData["aesEncryptKey"]
		];
     	$pushDataEncryp = RsaEncryp::pushDataEncrypt(json_encode($pushData));
      /*HistoryMsg::insertDb($newData);
      //离线表的发送运用队列，优先个人类型消息
      MsgOffLine::insertDb($newData); */
      $server = ServerManager::getInstance()->getSwooleServer();
       //$fd = $server->getClientInfo($redis->get($resultData["decryptData"]["targetId"]));
      //判断是否是群组消息
      //接收的时候存入消息历史表
      //个人消息发送
      if($resultData["decryptData"]["conversationType"] == 1){
        $userfd = $redis->get($resultData["decryptData"]["targetId"]);
       	$fdinfo = $server->getClientInfo($userfd);
        //判断该用户的fd是否在线，不在线存入离线表
        if(!empty($fdinfo)){
          //需要统计所有的未读消息并拼接进行发送
          $unreadCount = $this->countUnread($resultData["decryptData"]["targetId"])+1;
          $pushResult = $server->push($userfd, json_encode(array('data'=>$resultData["encryptContent"],'sign'=>$resultData["sign"],'aesEncryptKey'=>$resultData["aesEncryptKey"],'unreadCount'=>$unreadCount)));
          if(!$pushResult){
            $this->response()->setMessage(json_encode(['code'=>2005,'result'=>'error','msg'=>'消息服务发送失败']));return;
          /* //个人进行消息重发(async)
            $taskClass = new SendFailTask(array('fd'=>$userfd,'content'=>json_encode(array('data'=>$resultData["encryptContent"],'sign'=>$resultData["sign"],'aesEncryptKey'=>$resultData["aesEncryptKey"],'unreadCount'=>$unreadCount))));
            $taskResult = \EasySwoole\EasySwoole\Swoole\Task\TaskManager::async($taskClass);
            if(!$taskResult){
              $this->response()->setMessage(json_encode(['code'=>2005,'result'=>'error','msg'=>'消息服务发送失败']));
              return;
            }*/
          }
          //存入历史消息表
          HistoryMsg::insertDb($newData);	
                    //苹果服务器消息推送
          $deviceToken =$redis->get('token'.$resultData["decryptData"]["targetId"])?:null;
          if(!empty($deviceToken)){
            
           	PushContent::appPush($deviceToken,$pushDataEncryp);
          }
        }else{
              //苹果服务器消息推送
          $deviceToken =$redis->get('token'.$resultData["decryptData"]["targetId"])?:null;
          if(!empty($deviceToken)){
           	PushContent::appPush($deviceToken,$pushDataEncryp,1);
          }
          
          //存入历史消息表
          HistoryMsg::insertDb($newData);	
          //存入离线消息，此处应用异步任务/mq
          MsgOffLine::insertDb($newData);
        }
      
      }else{
        //群组消息处理
        if(empty($resultData["decryptData"]["targetId"])){$this->response()->setMessage(json_encode(['code'=>2001,'result'=>'error','msg'=>'群组号为空']));return;}
       
        $memberList = msgpack_unpack($redis->get($resultData["decryptData"]["targetId"]));
		
        $newData["groupUserIds"] =implode(',',$memberList);
        //群组消息推送（自带消息发送失败重发）
        $groupSendResult = GroupSend::send($redis,$server,$resultData,$newData,$pushDataEncryp);
        if(!$groupSendResult){$this->response()->setMessage(json_encode(['code'=>2005,'result'=>'error','msg'=>'消息发送失败']));return;}
      }
    }
        

   	//查询此人的未读消息总数(1)
  	//2已读
    public function countUnread($userid=0){
        $dbs = MysqlPool::defer();
       	$server = ServerManager::getInstance()->getSwooleServer();
        $str = "select fromUserId from bjyadmin_histroymsg where toUserId = ".$userid . " and readStatus = 1"; //and channelType ='0'
        $result = $dbs->rawQuery($str);
        return count($result);
    }
  	//查询这个群组的成员"sendUserId"
    public function getGroupUserId($groupId=0,$sendUserId){
        $dbs = MysqlPool::defer();
       	$server = ServerManager::getInstance()->getSwooleServer();
        $str = "select userid from bjyadmin_chatjoiner where groupid = ".$groupId . " and userid != ".$sendUserId; //and channelType ='0'
        $result = $dbs->rawQuery($str);
        return count($result);
    }
  
  
	//推送所有用户
    function delay()
    {
        //$this->response()->setMessage('this is delay action');
        $client = $this->caller()->getClient();
        // 异步推送, 这里直接 use fd也是可以的
        TaskManager::async(function () use ($client){
            $server = ServerManager::getInstance()->getSwooleServer();
            $i = 0;
            while ($i < 5) {
                sleep(1);
                $server->push($client->getFd(),json_encode(array('content'=>time())));
                $i++;
            }
        });
    }
  
  
 
 
}